package com.homestead.config;

import com.homestead.codec.FastJsonCodec;
import org.junit.platform.commons.util.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisConfig {
    @Bean
    @ConditionalOnProperty(name="redisson.single-address")
    RedissonClient redissonSingle(RedisProperties properties) {
        Config config = new Config();
        config.setCodec(FastJsonCodec.INSTANCE);
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(properties.getSingleAddress())
                .setTimeout(properties.getTimeout()).setConnectTimeout(properties.getTimeout())
                .setConnectionPoolSize(properties.getConnectionPoolSize())
                .setConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize());

        if(StringUtils.isNotBlank(properties.getPassword())) {
            serverConfig.setPassword(properties.getPassword());
        }
        return Redisson.create(config);
    }

    @Bean
    @ConditionalOnProperty(name="redisson.single-address")
    Jedis jedisSingle(RedisProperties properties) {

        String clusterAddresses = properties.getSingleAddress();

        String addrStr = clusterAddresses.substring(clusterAddresses.indexOf("/") + 2);

        String[] addrFull = addrStr.split(":");
        Jedis jedis = new Jedis(addrFull[0].trim(), Integer.parseInt(addrFull[1].trim()), properties.getTimeout());

        if (StringUtils.isNotBlank(properties.getPassword())) {
            jedis.auth(properties.getPassword());
        }

        return jedis;
    }

    //@Bean
    @ConditionalOnProperty(name="redisson.cluster-addresses")
    RedissonClient redissonCuster(RedisProperties properties) {
        Config config = new Config();
        String[] addressesStr = properties.getClusterAddresses().split(",");
        ArrayList<String> addressList = new ArrayList<>();
        for (String str : addressesStr) {
            addressList.add("redis://"+str.trim());
        }

        String[] clusterAddresses = addressList.toArray(new String[0]);
        ClusterServersConfig clusterServersConfig = config
                .useClusterServers()
                .addNodeAddress(clusterAddresses)
                .setMasterConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize())
                .setSlaveConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize())
                .setSubscriptionConnectionMinimumIdleSize(properties.getConnectionMinimumIdleSize())
               .setTimeout(properties.getTimeout())
                ;

        if(StringUtils.isNotBlank(properties.getPassword())) {
            clusterServersConfig.setPassword(properties.getPassword());
        }
        return Redisson.create(config);
    }

    @Bean
    @ConditionalOnProperty(name="redisson.cluster-addresses")
    JedisCluster jedisCluster(RedisProperties properties) {

        String clusterAddresses = properties.getClusterAddresses();

        String[] addrStr = clusterAddresses.split(",");

        Set<HostAndPort> hostAndPorts = new HashSet<>();
        for (String addr : addrStr) {
            String[] split = addr.split(":");
            HostAndPort hostAndPort = new HostAndPort(split[0].trim(), Integer.parseInt(split[1].trim()));
            hostAndPorts.add(hostAndPort);
        }

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(100);
        jedisPoolConfig.setMaxTotal(500);
        jedisPoolConfig.setMinIdle(properties.getConnectionMinimumIdleSize());
        jedisPoolConfig.setMaxWaitMillis(2000); // 设置2秒
        jedisPoolConfig.setTestOnBorrow(true);

        if (StringUtils.isBlank(properties.getPassword())) {
            return new JedisCluster(hostAndPorts, properties.getTimeout(), properties.getTimeout(), 5, jedisPoolConfig);
        }

        return new JedisCluster(hostAndPorts, properties.getTimeout(), properties.getTimeout(), 5, properties.getPassword(), jedisPoolConfig);
    }
}
